import FYUtility from "./FYUtility";

/**
 * 地图网格字典工具
 * 用途：
 *      1.生成对象时，防止重叠。(当地图比较大，网格方块比较小时，网格方块太多会造成性能问题，暂时移除相关操作)
 *      2.获取特定区域内的对象。
 */
export default class FYMapGridDict {
    /** 网格字典 将对象根据特定大小区域分类 */
    private _dictGrid = {};
    /** 网格方格宽度 */
    private _gridCellWidth: number = 10;
    /** 网格方格高度 */
    private _gridCellHeight: number = 10;
    /** 地图宽度 */
    private _mapWidth: number = 3000;
    /** 地图高度 */
    private _mapHeight: number = 3000;
    /** 空余网格字典 */
    // private _dictSpareGridKey = {};

    public constructor(cellWidth, cellHeight, mapWidth, mapHeight) {
        this._gridCellWidth = cellWidth;
        this._gridCellHeight = cellHeight;
        this._mapWidth = mapWidth;
        this._mapHeight = mapHeight;
        this._dictGrid = {};

        // this.generalSpareGridKeyList();
    }

    /**
     * 生成空余关键字列表
     */
    public generalSpareGridKeyList() {
        let xMin = Math.floor(-this._mapWidth / 2 / this._gridCellWidth);
        let xMax = Math.floor(this._mapWidth / 2 / this._gridCellWidth);
        let yMin = Math.floor(-this._mapHeight / 2 / this._gridCellHeight);
        let yMax = Math.floor(this._mapHeight / 2 / this._gridCellHeight);

        // this._dictSpareGridKey = {};
        // for (let i = xMin; i <= xMax; i++) {
        //     for (let j = yMin; j <= yMax; j++) {
        //         this._dictSpareGridKey[i + "_" + j] = 0;
        //     }
        // }
    }

    /**
     * 清空字典
     */
    public clearDict() {
        this._dictGrid = {};

        // this.generalSpareGridKeyList();
    }

    /** 获取字典 */
    public getDict() {
        return this._dictGrid;
    }

    /**
     * 计算网格关键字
     * @param pos 位置
     */
    public calcGridKey(pos: cc.Vec2) {
        let x = Math.floor(pos.x / this._gridCellWidth);
        let y = Math.floor(pos.y / this._gridCellHeight);
        let key = x + "_" + y
        return key;
    }

    /**
     * 关键字转坐标
     * @param key 关键字
     */
    // public calcKeyToPos(key: string) {
    //     let listKey = key.split("_");
    //     let x = Number(listKey[0]) * this._gridCellWidth;
    //     let y = Number(listKey[1]) * this._gridCellHeight;

    //     return new cc.Vec2(x, y);
    // }

    /**
     * 将对象添加到网格字典
     * @param node 对象
     */
    public addToDictGrid(node: cc.Node) {
        let pos = node.position;
        let key = this.calcGridKey(pos);

        if (!this._dictGrid[key]) {
            this._dictGrid[key] = [];
        }
        this._dictGrid[key].push(node);

        // if (this._dictSpareGridKey[key]) {
        //     delete this._dictSpareGridKey[key];
        // }
    }

    /**
     * 从特定区域拿对象
     * @param area 检测对象的区域
     */
    public getObjsFromDictGridWithArea(area: cc.Rect): any[] {
        let v2LeftTop = new cc.Vec2(area.xMin, area.yMin);
        let v2RightBottom = new cc.Vec2(area.xMax, area.yMax);
        this.checkPosInGrid(v2LeftTop);
        this.checkPosInGrid(v2RightBottom);

        let xMin = Math.floor(v2LeftTop.x / this._gridCellWidth);
        let xMax = Math.floor(v2RightBottom.x / this._gridCellWidth);
        let yMin = Math.floor(v2LeftTop.y / this._gridCellHeight);
        let yMax = Math.floor(v2RightBottom.y / this._gridCellHeight);

        let listObj = [];
        for (let i = xMin; i <= xMax; i++) {
            for (let j = yMin; j <= yMax; j++) {
                let key = i + "_" + j;
                if (this._dictGrid[key]) {
                    listObj = listObj.concat(this._dictGrid[key]);
                }
            }
        }

        return listObj;
    }

    /**
     * 移除对象
     * @param node 对象
     */
    public removeObjFromDictGrid(node: cc.Node) {
        if (!node) {
            return;
        }
        let pos = node.position;
        let key = this.calcGridKey(pos);
        if (this._dictGrid[key]) {
            for (let i = 0; i < this._dictGrid[key].length; i++) {
                if (node.uuid == this._dictGrid[key][i].uuid) {
                    FYUtility.removeArrayValueByIndex(this._dictGrid[key], i);
                    if (this._dictGrid[key].length === 0) {
                        delete this._dictGrid[key];
                        // this._dictSpareGridKey[key] = 0;
                    }
                    return;
                }
            }
        }
    }

    /**
     * 校验位置是否在区域内 如果不在则矫正
     * @param pos 位置
     */
    public checkPosInGrid(pos: cc.Vec2) {
        if (pos.x < -this._mapWidth / 2) {
            pos.x = -this._mapWidth / 2;
        }
        if (pos.x > this._mapWidth / 2) {
            pos.x = this._mapWidth / 2;
        }
        if (pos.y < -this._mapHeight / 2) {
            pos.y = -this._mapHeight / 2;
        }
        if (pos.y > this._mapHeight / 2) {
            pos.y = this._mapHeight / 2;
        }
    }

    /**
     * 获取空余网格列表
     */
    // public getSpareGridList() {
    //     return Object.keys(this._dictSpareGridKey);
    // }
}
